`include "define.svh"

module pc_reg(
    input wire							rst,
    input wire							clk,
    input wire                          ctrl_stall_i,
    input wire							branch_flag_i,
    input wire [`PC_WIDTH - 1 : 0]		branch_addr_i,
    input wire                          data_ok,
    input wire                          addr_ok,
    input wire                          is_exc_i,
    input wire                          is_eret_i,
    input wire [`PC_WIDTH - 1 : 0]      epc_i,
    
    output reg                          inst_sram_en,
    output reg [`PC_WIDTH - 1 : 0]      inst_sram_addr,
    input wire [`REG_WIDTH - 1 : 0]     inst_sram_rdata,
    
    output reg [`REG_WIDTH - 1 : 0]     inst_o,
    output reg [`PC_WIDTH - 1 : 0]		pc_o
);
  
    reg is_exc;
    reg is_eret;
    
    always_ff @(posedge clk)
        if (rst == `reset)      is_exc <= `false;
        else if (is_exc_i)      is_exc <= `true;
        else if (data_ok)       is_exc <= `false;
    always_ff @(posedge clk)
        if (rst == `reset)      is_eret <= `false;
        else if (is_eret_i)     is_eret <= `true;
        else if (data_ok)       is_eret <= `false;
    
    always_ff @( posedge clk )
        if ( rst == `reset )                pc_o <= `NOP_PC;
        else begin
            if (ctrl_stall_i)               pc_o <= pc_o;
            else if (is_eret_i | is_eret)   pc_o <= epc_i;
            else if (is_exc | is_exc_i)     pc_o <= 32'hBFC00380;
            else if (branch_flag_i)         pc_o <= branch_addr_i;
            else                            pc_o <= pc_o + 4;
        end
        
    always_comb inst_sram_en = `true;
    
    always_comb begin
        if (is_eret_i | is_eret)        inst_sram_addr = epc_i;
        else if (is_exc | is_exc_i)     inst_sram_addr = 32'hBFC00380;
        else if (branch_flag_i)         inst_sram_addr = branch_addr_i;
        else                            inst_sram_addr = pc_o + 4;
    end
    
    always_ff @(posedge clk)
        if (data_ok)                    inst_o <= inst_sram_rdata;
    
endmodule
